﻿
namespace LightCAD.Drawing.Actions
{
    public class PointInputer : Inputer
    {
        private Vector2 inputp;
        private Vector2 extInputp;
        private string option;
        public PointInputer(IDocumentEditor docEditor) : base(docEditor)
        {
        }
        public Vector2 PrePoint { get; set; }
        public async Task<InputResult> Execute(string prompt)
        {
            inputp = null;
            option = null;
            this.vportRt.SnapRt = new SnapRuntime(this.vportRt);
            var vportRt = this.vportRt;
            vportRt.CursorType = LcCursorType.InputPoint;
            this.commandCtrl.SetAlternateCommandState(false);
            this.Reset();
            this.AttachEvents();
            Prompt(prompt);
            await WaitFinish();
            this.DetachEvents();

            this.commandCtrl.SetAlternateCommandState(true);
            vportRt.CursorType = LcCursorType.SelectElement;
            this.vportRt.SnapRt = null;
            if (this.isCancelled)
                return null;
            else
            {
                return new InputResult(inputp, option) { Extent = this.extInputp };
            }
        }

        protected override void OnViewportMouseMove(MouseEventRuntime e)
        {
            var mp = this.vportRt.ConvertScrToWcs(e.Location.ToVector2d());
            if (this.vportRt.SnapRt==null)
            {
                return;
            }
            this.vportRt.SnapRt.MouseMove(mp, PrePoint);
        }
        protected override void OnViewportMouseHoverStart(MouseEventRuntime e)
        {
            if (this.vportRt.SnapRt == null) return;
            var mp = this.vportRt.ConvertScrToWcs(e.Location.ToVector2d());
            this.vportRt.SnapRt.MouseHover(mp);
        }
        protected override void OnViewportMouseDown(MouseEventRuntime e)
        {            //这里要返回世界坐标，因为开启捕捉之后，就没有屏幕坐标了
            this.inputp = this.vportRt.ConvertScrToWcs(e.Location.ToVector2d());
            this.PrePoint = this.vportRt.ConvertScrToWcs(e.Location.ToVector2d());
            if (this.vportRt.SnapRt?.Current != null)
            {
                this.extInputp = this.inputp;
                this.inputp = this.vportRt.SnapRt.Current.SnapPoint;
            }
            this.commandCtrl.WriteInfo(this.commandCtrl.GetPrompt());
            this.Finish();
        }

        protected override void OnInputBoxKeyDown(KeyEventRuntime e)
        {
            base.OnInputBoxKeyDown(e);
            if (e.KeyCode == 13 || e.KeyCode == 32)//Keys.Enter
            {
                var text = this.commandCtrl.GetInputText().Trim();
                this.commandCtrl.SetInputText(string.Empty);
                //TODO:检查可以输入的字符
                this.inputp = InputUtils.ParsePoint(text);
                if (this.inputp == null)
                {
                    this.option = text;
                    if (this.option == string.Empty)
                    {
                        this.option = " ";
                    }
                }
                this.Finish();
            }
        }

        protected override void OnViewportKeyDown(KeyEventRuntime e)
        {
            base.OnViewportKeyDown(e);
            if (e.KeyCode == 13 || e.KeyCode == 32)//Keys.Enter
            {
                var text = vportRt.Control.GetInputText().Trim();
                vportRt.Control.SetInputText(string.Empty);
                this.inputp = this.vportRt.ScrToWcs.MultiplyPoint(vportRt.PointerMovedPosition.ToVector2d());
                this.extInputp = this.inputp;
                if (this.vportRt.SnapRt.Current != null && this.vportRt.SnapRt.Current.ExtType == "HorzVert")
                {
                    this.inputp = this.vportRt.SnapRt.Current.SnapPoint;
                }
                if (e.KeyCode == 13) text = " ";
                //TODO:检查可以输入的字符
                if (double.TryParse(text, out double val))
                {
                    Vector2 pointB = (Vector2)this.inputp;
                    Vector2 direction = (pointB - PrePoint).Normalize();
                    this.option = val.ToString();
                    PrePoint = PrePoint + direction * double.Parse(this.option);
                }
                else
                {
                    this.inputp = null;  
                    this.extInputp = null;

                    this.option = text;
                }
                this.Finish();
            }
        }
    }
}
